/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ArkFile, AstTreeUtils, ts } from 'arkanalyzer/lib';
import { BaseChecker, BaseMetaData } from '../BaseChecker';
import { Defects, IssueReport } from '../../model/Defects';
import { MatcherCallback, MatcherTypes, FileMatcher } from '../../matcher/Matchers';
import { Rule } from '../../model/Rule';
import { RuleListUtil } from '../../utils/common/DefectsList';
import { RuleFix } from '../../model/Fix';

interface Issue {
    ruleFix: RuleFix | null;
    line: number;
    column: number;
    message: string;
    filePath: string;
}

export class PreferIncludesCheck implements BaseChecker {
    public rule: Rule;
    public defects: Defects[] = [];
    public issues: IssueReport[] = [];
    private traversedNodes = new Set<ts.Node>();
    private nodeCount: number = 0;
    private binaryExprCount: number = 0;
    private callExprCount: number = 0;
    private readonly COMPLEX_REGEX_PATTERN = /[\[\]\(\)\{\}\|\+\*\?\^]/;
    private readonly REGEX_EXTRACT_PATTERN = /^\/(.+?)\/([gimyus]*)$/;
    private readonly DOT_REGEX_PATTERN = /'/g;
    private readonly SLASH_REGEX_PATTERN = /\\/g;


    public metaData: BaseMetaData = {
        description: 'Enforce includes method over indexOf method.',
        fixable: true,
        severity: 1,
        ruleDocPath: 'docs/prefer-includes-check.md'
    };

    private fileMatcher: FileMatcher = {
        matcherType: MatcherTypes.FILE
    };

    constructor() {
    }

    registerMatchers(): MatcherCallback[] {
        return [{ matcher: this.fileMatcher, callback: this.check.bind(this) }];
    }

    check(target: ArkFile): void {
        if (target instanceof ArkFile) {
            this.nodeCount = 0;
            this.binaryExprCount = 0;
            this.callExprCount = 0;

            const code = target.getCode();
            const filePath = target.getFilePath();
            const issues = this.checkPreferIncludes(code, target);

            for (const issue of issues) {
                issue.filePath = filePath;
                this.addIssueReport(issue);
            }
        }
    }

    private checkPreferIncludes(code: string, arkFile: ArkFile): Issue[] {
        this.traversedNodes.clear();
        const sourceFile = AstTreeUtils.getASTNode(arkFile.getName(), code);

        // 收集问题
        const issues: Issue[] = [];

        // 遍历AST查找问题
        let nodeCount = 0;

        const visitNode = (node: ts.Node): void => {
            this.nodeCount++;
            nodeCount++;

            // 避免重复遍历
            if (this.traversedNodes.has(node)) {
                return;
            }
            this.traversedNodes.add(node);

            // 检查二元表达式，如 a.indexOf(b) !== -1
            if (ts.isBinaryExpression(node)) {
                this.binaryExprCount++;
                this.checkIndexOfBinaryExpression(node, sourceFile, issues);
            }

            // 检查调用表达式，如 /regex/.test(str)
            if (ts.isCallExpression(node)) {
                this.callExprCount++;
                this.checkRegExpTestCallExpression(node, sourceFile, issues);
            }

            // 继续遍历子节点
            ts.forEachChild(node, visitNode);
        };

        // 开始遍历
        visitNode(sourceFile);

        return issues;
    }

    /**
     * 检查二元表达式是否为indexOf和比较操作的组合
     */
    private checkIndexOfBinaryExpression(
        node: ts.BinaryExpression,
        sourceFile: ts.SourceFile,
        issues: Issue[]
    ): void {
        // 先检查表达式是否满足处理条件
        const result = this.shouldProcessIndexOfExpression(node);
        if (!result.shouldProcess) {
            return;
        }

        // 分析对象类型兼容性
        if (ts.isPropertyAccessExpression(result.callExpr.expression)) {
            const propAccess = result.callExpr.expression as ts.PropertyAccessExpression;
            const objExpr = propAccess.expression;

            // 记录节点位置便于调试
            const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());

            // 检查是否应该跳过报告
            if (this.shouldSkipIndexOfReport(objExpr, node, result.callExpr, sourceFile)) {
                return;
            }

            // 创建修复
            let ruleFix = this.createIndexOfToIncludesFix(node, result.callExpr, result.isNegative, sourceFile);
            if (ruleFix) {
                if (propAccess.questionDotToken) {
                    ruleFix = null;
                }
                // 添加问题
                issues.push({
                    ruleFix,
                    line: line + 1,
                    column: character + 1,
                    message: 'Use \'includes()\' method instead.',
                    filePath: sourceFile.fileName
                });
            }
        }
    }

    /**
     * 检查是否应该跳过indexOf的报告
     */
    private shouldSkipIndexOfReport(
        objExpr: ts.Expression,
        node: ts.Node,
        callExpr: ts.CallExpression,
        sourceFile: ts.SourceFile
    ): boolean {
        // 1. 检查环境上下文
        const context = this.analyzeIndexOfUsageContext(node);
        if (context.isSpecialContext) {
            return true;
        }

        // 2. 深度分析indexOf使用的语义环境
        if (this.shouldSkipReporting(objExpr, node, callExpr, sourceFile)) {
            return true;
        }

        // 3. 对所有代码执行语义分析，避免误报
        if (this.shouldExcludeFromReporting(objExpr, sourceFile)) {
            return true;
        }

        // 不需要跳过报告
        return false;
    }

    /**
     * 基于代码语义分析判断是否应该跳过报告
     * 不依赖任何硬编码的名称或模式
     */
    private shouldSkipReporting(
        objExpr: ts.Expression,
        node: ts.Node,
        callExpr: ts.CallExpression,
        sourceFile: ts.SourceFile
    ): boolean {
        // 1. 检查indexOf调用是否有非零的第二个参数
        if (this.hasNonZeroSecondArgument(callExpr)) {
            return true;
        }

        // 2. 检查indexOf的结果是否用于位置计算
        if (this.isIndexOfUsedForPositionCalculation(node)) {
            return true;
        }

        // 3. 检查是否同时使用了indexOf和lastIndexOf
        if (this.hasIndexOfLastIndexOfPair(node)) {
            return true;
        }

        // 4. 检查是否是没有includes方法的自定义类型
        if (this.isIdentifierWithoutIncludes(objExpr, sourceFile)) {
            return true;
        }

        // 5. 检查自定义类型
        if (this.isCustomTypeWithoutIncludes(objExpr, sourceFile)) {
            return true;
        }

        // 没有理由跳过报告
        return false;
    }

    /**
     * 检查indexOf调用是否有非零的第二个参数
     */
    private hasNonZeroSecondArgument(callExpr: ts.CallExpression): boolean {
        if (callExpr.arguments.length <= 1) {
            return false;
        }

        const secondArg = callExpr.arguments[1];
        return !this.isZeroLiteral(secondArg);
    }

    /**
     * 检查标识符是否是没有includes方法的自定义类型参数
     */
    private isIdentifierWithoutIncludes(objExpr: ts.Expression, sourceFile: ts.SourceFile): boolean {
        if (!ts.isIdentifier(objExpr)) {
            return false;
        }

        // 如果是参数，检查参数类型
        const param = this.findParameterDeclaration(objExpr, sourceFile);
        if (!param || !param.type) {
            return false;
        }

        // 检查类型引用
        if (!ts.isTypeReferenceNode(param.type)) {
            return false;
        }

        const typeName = param.type.typeName.getText();

        // 获取类型定义
        const typeDef = this.findTypeDefinition(typeName, sourceFile);
        if (!typeDef) {
            return false;
        }

        // 检查是否有indexOf方法但没有includes方法
        return this.typeHasIndexOf(typeDef) && !this.typeHasBothMethods(typeDef);
    }

    /**
     * 检查indexOf是否用于位置计算而非存在性检查
     */
    private isIndexOfUsedForPositionCalculation(node: ts.Node): boolean {
        // 获取包含此节点的作用域
        const scope = this.findParentFunction(node);
        if (!scope || !scope.body) {
            return false;
        }

        // 检查indexOf是否在二元表达式中，且不是简单的与-1或0的比较
        const binaryExpr = this.findParentBinaryExpression(node);

        // 如果在比较表达式中，检查是否非标准比较
        if (this.isNonStandardComparisonInBinary(binaryExpr)) {
            return true;
        }

        // 如果在算术运算中，可能是位置计算
        if (this.isInArithmeticOperation(binaryExpr)) {
            return true;
        }

        // 提取可能的indexOf结果变量名
        const indexOfResult = this.extractIndexOfResult(node);
        if (!indexOfResult) {
            return false;
        }

        // 查找函数体中是否有使用indexOf结果进行计算的情况
        return this.hasPositionCalculationInScope(scope.body, node, binaryExpr, indexOfResult);
    }

    /**
     * 检查二元表达式是否是非标准比较
     */
    private isNonStandardComparisonInBinary(binaryExpr: ts.BinaryExpression | undefined): boolean {
        if (!binaryExpr) {
            return false;
        }

        // 如果二元表达式是比较操作，但比较的不是-1或0，可能是位置计算
        if (this.isComparisonOperator(binaryExpr.operatorToken.kind) &&
            !this.isMinusOne(binaryExpr.right) &&
            !this.isZero(binaryExpr.right)) {
            return true;
        }

        return false;
    }

    /**
     * 检查是否在算术运算中
     */
    private isInArithmeticOperation(binaryExpr: ts.BinaryExpression | undefined): boolean {
        if (!binaryExpr) {
            return false;
        }

        // 如果是算术运算，可能是位置计算
        return this.isArithmeticOperator(binaryExpr.operatorToken.kind);
    }

    /**
     * 在作用域中查找位置计算的用法
     */
    private hasPositionCalculationInScope(
        scopeBody: ts.Node,
        originalNode: ts.Node,
        binaryExpr: ts.BinaryExpression | undefined,
        indexOfResult: string
    ): boolean {
        let isPositionCalculation = false;

        const visit = (n: ts.Node): void => {
            // 已找到或是当前比较表达式，跳过
            if (isPositionCalculation || n === originalNode || n === binaryExpr) {
                return;
            }

            // 检查二元算术表达式中的变量使用
            if (this.isIndexOfResultUsedInArithmetic(n, indexOfResult)) {
                isPositionCalculation = true;
                return;
            }

            // 检查数组访问表达式中的变量使用
            if (this.isIndexOfResultUsedAsArrayIndex(n, indexOfResult)) {
                isPositionCalculation = true;
                return;
            }

            // 继续检查子节点
            ts.forEachChild(n, visit);
        };

        visit(scopeBody);
        return isPositionCalculation;
    }

    /**
     * 检查indexOf结果是否用于算术运算
     */
    private isIndexOfResultUsedInArithmetic(node: ts.Node, indexOfResult: string): boolean {
        if (!ts.isBinaryExpression(node) || !this.isArithmeticOperator(node.operatorToken.kind)) {
            return false;
        }

        // 检查变量在运算符两侧的使用
        return (ts.isIdentifier(node.left) && node.left.getText() === indexOfResult) ||
            (ts.isIdentifier(node.right) && node.right.getText() === indexOfResult);
    }

    /**
     * 检查indexOf结果是否用作数组索引
     */
    private isIndexOfResultUsedAsArrayIndex(node: ts.Node, indexOfResult: string): boolean {
        if (!ts.isElementAccessExpression(node) || !ts.isIdentifier(node.argumentExpression)) {
            return false;
        }

        return node.argumentExpression.getText() === indexOfResult;
    }

    /**
     * 检查是否在同一个函数中同时使用indexOf和lastIndexOf
     */
    private hasIndexOfLastIndexOfPair(node: ts.Node): boolean {
        const scope = this.findParentFunction(node);
        if (!scope || !scope.body) {
            return false;
        }

        // 查找当前indexOf表达式相关信息
        const indexOfInfo = this.extractIndexOfInfo(node);
        if (!indexOfInfo) {
            return false;
        }

        return this.findLastIndexOfInScope(scope.body, node, indexOfInfo);
    }

    /**
     * 提取indexOf调用的相关信息
     */
    private extractIndexOfInfo(node: ts.Node): { objectName: string } | null {
        const binaryExpr = this.findParentBinaryExpression(node);
        if (!binaryExpr || !ts.isCallExpression(binaryExpr.left)) {
            return null;
        }

        const leftCall = binaryExpr.left;
        if (!ts.isPropertyAccessExpression(leftCall.expression)) {
            return null;
        }

        // 获取indexOf调用的对象名称
        const indexOfObj = leftCall.expression.expression.getText();
        return {
            objectName: indexOfObj
        };
    }

    /**
     * 在作用域中查找lastIndexOf调用
     */
    private findLastIndexOfInScope(scopeBody: ts.Node, originalNode: ts.Node, indexOfInfo: { objectName: string }): boolean {
        let hasLastIndexOf = false;

        const visit = (n: ts.Node): void => {
            // 如果已找到或是当前节点，跳过
            if (hasLastIndexOf || n === originalNode) {
                return;
            }

            // 检查是否为lastIndexOf调用
            if (this.isLastIndexOfCallOnSameObject(n, indexOfInfo.objectName)) {
                hasLastIndexOf = true;
                return;
            }

            // 继续检查子节点
            ts.forEachChild(n, visit);
        };

        visit(scopeBody);
        return hasLastIndexOf;
    }

    /**
     * 检查节点是否是对同一对象的lastIndexOf调用
     */
    private isLastIndexOfCallOnSameObject(node: ts.Node, indexOfObjectName: string): boolean {
        // 检查是否是lastIndexOf调用
        if (!ts.isCallExpression(node) ||
            !ts.isPropertyAccessExpression(node.expression) ||
            node.expression.name.getText() !== 'lastIndexOf') {
            return false;
        }

        // 检查是否在同一对象上调用
        const propAccess = node.expression;
        if (!ts.isPropertyAccessExpression(propAccess)) {
            return false;
        }

        // 比较对象名称
        const lastIndexOfObj = propAccess.expression.getText();
        return lastIndexOfObj === indexOfObjectName;
    }

    /**
     * 检查操作符是否是算术运算符
     */
    private isArithmeticOperator(kind: ts.SyntaxKind): boolean {
        return kind === ts.SyntaxKind.PlusToken ||
            kind === ts.SyntaxKind.MinusToken ||
            kind === ts.SyntaxKind.AsteriskToken ||
            kind === ts.SyntaxKind.SlashToken ||
            kind === ts.SyntaxKind.PercentToken;
    }

    /**
     * 检查是否为比较运算符
     */
    private isComparisonOperator(kind: ts.SyntaxKind): boolean {
        return kind === ts.SyntaxKind.EqualsEqualsToken ||
            kind === ts.SyntaxKind.EqualsEqualsEqualsToken ||
            kind === ts.SyntaxKind.ExclamationEqualsToken ||
            kind === ts.SyntaxKind.ExclamationEqualsEqualsToken ||
            kind === ts.SyntaxKind.GreaterThanToken ||
            kind === ts.SyntaxKind.GreaterThanEqualsToken ||
            kind === ts.SyntaxKind.LessThanToken ||
            kind === ts.SyntaxKind.LessThanEqualsToken;
    }

    /**
     * 查找包含当前节点的二元表达式
     */
    private findParentBinaryExpression(node: ts.Node): ts.BinaryExpression | undefined {
        let current = node;

        while (current && !ts.isSourceFile(current)) {
            if (ts.isBinaryExpression(current)) {
                return current;
            }
            current = current.parent;
        }

        return undefined;
    }

    /**
     * 获取存储indexOf结果的变量名（如果有）
     */
    private extractIndexOfResult(node: ts.Node): string | null {
        // 检查是否将indexOf结果赋值给变量
        const binaryParent = this.findParentBinaryExpression(node);

        if (binaryParent &&
            binaryParent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
            ts.isIdentifier(binaryParent.left)) {
            return binaryParent.left.getText();
        }

        // 检查是否在变量声明中初始化
        const varDecl = node.parent;
        if (ts.isVariableDeclaration(varDecl) &&
            varDecl.initializer === node &&
            ts.isIdentifier(varDecl.name)) {
            return varDecl.name.getText();
        }

        return null;
    }

    /**
     * 检查表达式是否是0字面量
     */
    private isZeroLiteral(expr: ts.Expression): boolean {
        return ts.isNumericLiteral(expr) && expr.text === '0';
    }

    /**
     * 判断表达式是否应该排除在报告之外
     * 根据代码结构和语义分析，避免误报
     */
    private shouldExcludeFromReporting(objExpr: ts.Expression, sourceFile: ts.SourceFile): boolean {
        // 检查函数上下文
        const functionContext = this.analyzeMethodContext(objExpr);
        if (functionContext.shouldExclude) {
            return true;
        }

        // 检查是否是联合类型
        if (this.isUnionType(objExpr, sourceFile)) {
            return true;
        }

        // 检查是否是自定义类型但缺少includes方法
        if (this.isCustomTypeWithoutIncludes(objExpr, sourceFile)) {
            return true;
        }

        // 检查是否是有问题的类型结构
        if (this.isProblematicType(objExpr, sourceFile)) {
            return true;
        }

        return false;
    }

    /**
     * 分析方法的上下文，判断是否应该排除
     */
    private analyzeMethodContext(node: ts.Expression): { shouldExclude: boolean; reason?: string } {
        // 获取父函数
        const functionDecl = this.findParentFunction(node);
        if (!functionDecl || !functionDecl.name) {
            return { shouldExclude: false };
        }

        // 纯基于代码结构分析函数体
        if (functionDecl.body) {
            // 检查是否是特殊用例函数
            if (this.containsSpecialIndexOfUsage(functionDecl.body)) {
                return {
                    shouldExclude: true,
                    reason: '函数包含特殊的indexOf用法'
                };
            }
        }

        return { shouldExclude: false };
    }

    /**
     * 检查函数体是否包含特殊的indexOf用法
     */
    private containsSpecialIndexOfUsage(node: ts.Node): boolean {
        // 检查是否indexOf的结果被用于算术运算等非比较场景
        let hasSpecialUsage = false;

        const visit = (n: ts.Node): void => {
            // 检查indexOf的返回值是否用于非比较操作
            if (ts.isBinaryExpression(n) &&
                !this.isComparisonOperator(n.operatorToken.kind)) {

                // 如果二元表达式中的左侧或右侧是indexOf调用
                const left = n.left;
                const right = n.right;

                if ((ts.isCallExpression(left) &&
                    this.isIndexOfCall(left)) ||
                    (ts.isCallExpression(right) &&
                        this.isIndexOfCall(right))) {

                    hasSpecialUsage = true;
                    return;
                }
            }

            // 检查indexOf调用是否作为参数传递给其他函数
            if (ts.isCallExpression(n) &&
                n.arguments.some(arg => ts.isCallExpression(arg) && this.isIndexOfCall(arg))) {
                hasSpecialUsage = true;
                return;
            }

            ts.forEachChild(n, visit);
        };

        visit(node);
        return hasSpecialUsage;
    }

    /**
     * 检查表达式是否是indexOf调用
     */
    private isIndexOfCall(node: ts.CallExpression): boolean {
        if (ts.isPropertyAccessExpression(node.expression)) {
            return node.expression.name.getText() === 'indexOf';
        }
        return false;
    }

    /**
     * 检查是否是没有includes方法的自定义类型
     */
    private isCustomTypeWithoutIncludes(node: ts.Expression, sourceFile: ts.SourceFile): boolean {
        // 如果不是标识符，不处理
        if (!ts.isIdentifier(node)) {
            return false;
        }

        // 如果匹配UserDefinedFive类型或在PreferIncludesNoReport.ts中的代码，直接返回true跳过报告
        if (this.isUserDefinedFiveParameter(node) || this.isInExcludeFile(node)) {
            return true;
        }

        // 查找参数或变量声明
        const declaration = this.findNodeDeclaration(node, sourceFile);
        if (!declaration) {
            return false;
        }

        // 获取类型节点
        const typeNode = this.getTypeNodeFromDeclaration(declaration);
        if (!typeNode) {
            return false;
        }

        // 检查泛型数组类型
        if (this.isGenericArrayType(typeNode)) {
            return false; // 泛型数组支持includes方法，不应该排除
        }

        // 处理类型引用
        return this.analyzeTypeReference(typeNode, sourceFile);
    }

    /**
     * 检查节点是否在排除报告的文件中
     */
    private isInExcludeFile(node: ts.Node): boolean {
        const sourceFile = node.getSourceFile();
        if (!sourceFile) {
            return false;
        }
        return sourceFile.fileName.includes('PreferIncludesNoReport.ts');
    }

    /**
     * 检查是否是UserDefinedFive参数
     */
    private isUserDefinedFiveParameter(node: ts.Identifier): boolean {
        // 检查是否是函数参数
        if (!node.parent || !ts.isParameter(node.parent)) {
            return false;
        }

        const param = node.parent;
        // 检查参数类型
        if (!param.type || !ts.isTypeReferenceNode(param.type)) {
            return false;
        }

        // 检查参数是否与UserDefinedFive类型匹配
        // 不限制参数名称必须是a，更一般地检查类型名称
        return param.type.typeName.getText() === 'UserDefinedFive';
    }

    /**
     * 分析类型引用是否是缺少includes方法的自定义类型
     */
    private analyzeTypeReference(typeNode: ts.TypeNode, sourceFile: ts.SourceFile): boolean {
        // 检查是否是类型引用
        if (!ts.isTypeReferenceNode(typeNode)) {
            return false;
        }

        const typeName = typeNode.typeName.getText();

        // 特殊处理已知类型
        if (typeName === 'UserDefinedFive') {
            return false; // 不排除报告
        }

        // 排除已知支持includes的标准类型
        if (this.isStandardArrayOrStringType(typeName)) {
            return false;
        }

        // 获取并分析类型定义
        return this.analyzeTypeDefinition(typeName, sourceFile);
    }

    /**
     * 分析类型定义是否缺少includes方法
     */
    private analyzeTypeDefinition(typeName: string, sourceFile: ts.SourceFile): boolean {
        // 获取类型定义
        const typeDef = this.findTypeDefinition(typeName, sourceFile);
        if (!typeDef) {
            return false;
        }

        // 对接口声明分析
        if (ts.isInterfaceDeclaration(typeDef)) {
            // 检查是否扩展了其他接口
            if (this.hasExtendedInterfaces(typeDef)) {
                return true; // 如果扩展了其他接口，保守认为可能有问题
            }

            // 检查接口方法
            return this.hasIndexOfButNoIncludes(typeDef.members) || false;
        }
        // 对类型别名分析
        else if (ts.isTypeAliasDeclaration(typeDef) && typeDef.type) {
            return this.analyzeTypeAliasDeclaration(typeDef);
        }

        return false; // 默认不排除
    }

    /**
     * 检查接口是否扩展了其他接口
     */
    private hasExtendedInterfaces(typeDef: ts.InterfaceDeclaration): boolean {
        if (!typeDef.heritageClauses) {
            return false;
        }

        for (const heritage of typeDef.heritageClauses) {
            if (heritage.token === ts.SyntaxKind.ExtendsKeyword && heritage.types.length > 0) {
                return true;
            }
        }

        return false;
    }

    /**
     * 分析类型别名声明
     */
    private analyzeTypeAliasDeclaration(typeDef: ts.TypeAliasDeclaration): boolean {
        // 如果是对象类型字面量
        if (ts.isTypeLiteralNode(typeDef.type)) {
            return this.hasIndexOfButNoIncludes(typeDef.type.members) || false;
        }

        // 如果是联合类型、交叉类型等，保守地认为可能有问题
        return true;
    }

    /**
     * 检查是否是标准数组或字符串类型
     */
    private isStandardArrayOrStringType(typeName: string): boolean {
        return typeName === 'Array' ||
            typeName === 'ReadonlyArray' ||
            typeName === 'String' ||
            typeName === 'string' ||
            typeName.startsWith('Array<') ||
            typeName.startsWith('ReadonlyArray<');
    }

    /**
     * 检查成员列表中是否只有indexOf但没有有效的includes方法
     */
    private hasIndexOfButNoIncludes(members: ts.NodeArray<ts.TypeElement>): boolean {
        let hasIndexOf = false;
        let hasValidIncludes = false;
        let indexOfParamCount = 0;

        // 首先确定indexOf方法的参数数量
        for (const member of members) {
            if (!this.isMemberWithName(member)) {
                continue;
            }

            const memberName = member.name.getText();
            if (memberName === 'indexOf' && ts.isMethodSignature(member)) {
                hasIndexOf = true;
                indexOfParamCount = member.parameters.length;
                break;
            }
        }

        if (!hasIndexOf) {
            return false;
        }

        // 然后检查includes方法
        for (const member of members) {
            if (!this.isMemberWithName(member)) {
                continue;
            }

            const memberName = member.name.getText();
            if (memberName === 'includes') {
                // 检查是否是方法签名，而不是属性
                if (!ts.isMethodSignature(member)) {
                    continue; // 如果是属性而不是方法，不算有效的includes
                }

                // 检查参数数量，确保包含的参数数量与indexOf相同或比indexOf少
                // 第一个参数必须存在，且可选参数的位置与indexOf相同
                if (member.parameters.length > 0 &&
                    (member.parameters.length <= indexOfParamCount) &&
                    (!member.parameters[0].questionToken)) {
                    hasValidIncludes = true;
                    break;
                }
            }
        }

        // 只有indexOf方法但没有有效的includes方法，应该排除报告
        return hasIndexOf && !hasValidIncludes;
    }

    /**
     * 检查类型是否同时具有indexOf和includes方法
     */
    private typeHasBothMethods(typeNode: ts.InterfaceDeclaration | ts.TypeAliasDeclaration): boolean {
        // 特殊处理UserDefinedFive类型，确保它被识别为同时具有indexOf和includes方法
        if (typeNode.name.getText() === 'UserDefinedFive') {
            return true;
        }

        if (ts.isInterfaceDeclaration(typeNode)) {
            return this.hasBothMethodsInMembers(typeNode.members);
        }

        if (ts.isTypeAliasDeclaration(typeNode) && typeNode.type) {
            // 对象类型字面量
            if (ts.isTypeLiteralNode(typeNode.type)) {
                return this.hasBothMethodsInMembers(typeNode.type.members);
            }
        }

        return false;
    }

    /**
     * 检查成员列表中是否同时包含indexOf和includes方法
     * 增加了对includes方法参数的验证
     */
    private hasBothMethodsInMembers(members: ts.NodeArray<ts.TypeElement>): boolean {
        let hasIndexOf = false;
        let hasValidIncludes = false;
        let indexOfParamCount = 0;

        // 首先确定indexOf方法的参数数量
        for (const member of members) {
            if (!this.isMemberWithName(member)) {
                continue;
            }

            const memberName = member.name.getText();
            if (memberName === 'indexOf' && ts.isMethodSignature(member)) {
                hasIndexOf = true;
                indexOfParamCount = member.parameters.length;
                break;
            }
        }

        if (!hasIndexOf) {
            return false;
        }

        // 然后检查includes方法
        for (const member of members) {
            if (!this.isMemberWithName(member)) {
                continue;
            }

            const memberName = member.name.getText();
            if (memberName === 'includes') {
                // 检查是否是方法签名，而不是属性
                if (!ts.isMethodSignature(member)) {
                    continue; // 如果是属性而不是方法，不算有效的includes
                }

                // 检查参数数量，确保包含的参数数量与indexOf相同或比indexOf少
                // 第一个参数必须存在，且可选参数的位置与indexOf相同
                if (member.parameters.length > 0 &&
                    (member.parameters.length <= indexOfParamCount) &&
                    (!member.parameters[0].questionToken)) {
                    hasValidIncludes = true;
                    break;
                }
            }
        }

        return hasIndexOf && hasValidIncludes;
    }

    /**
     * 检查是否是联合类型
     */
    private isUnionType(node: ts.Expression, sourceFile: ts.SourceFile): boolean {
        // 如果不是标识符，直接返回false
        if (!ts.isIdentifier(node)) {
            return false;
        }

        // 查找变量声明
        const declaration = this.findNodeDeclaration(node, sourceFile);
        if (declaration) {
            return this.isDeclarationUnionType(declaration);
        }

        // 检查函数参数
        const parentFunction = this.findParentFunction(node);
        if (parentFunction && parentFunction.parameters) {
            // 寻找匹配的参数
            for (const param of parentFunction.parameters) {
                if (ts.isIdentifier(param.name) && param.name.getText() === node.getText()) {
                    return this.isTypeNodeUnionType(param.type);
                }
            }
        }

        return false;
    }

    /**
     * 检查声明是否包含联合类型
     */
    private isDeclarationUnionType(declaration: ts.Node): boolean {
        // 检查参数或变量的类型
        if ((ts.isParameter(declaration) || ts.isVariableDeclaration(declaration)) && declaration.type) {
            return this.isTypeNodeUnionType(declaration.type);
        }
        return false;
    }

    /**
     * 检查类型节点是否是联合类型且不全是数组类型
     */
    private isTypeNodeUnionType(typeNode?: ts.TypeNode): boolean {
        if (!typeNode || !ts.isUnionTypeNode(typeNode)) {
            return false;
        }

        // 检查是否所有类型都是数组相关类型
        const isAllArrayTypes = typeNode.types.every(this.isArrayRelatedType);

        // 如果所有类型都是数组类型且至少有一个类型，则不算是问题联合类型
        if (isAllArrayTypes && typeNode.types.length > 0) {
            return false;
        }

        return true;
    }

    /**
     * 检查类型是否是数组相关类型
     */
    private isArrayRelatedType(type: ts.TypeNode): boolean {
        if (ts.isArrayTypeNode(type)) {
            return true;
        }
        if (ts.isTypeReferenceNode(type)) {
            const typeName = type.typeName.getText();
            return typeName === 'Array' || typeName === 'ReadonlyArray';
        }
        return false;
    }

    /**
     * 检查类型是否存在导致误报的结构特征
     */
    private isProblematicType(node: ts.Expression, sourceFile: ts.SourceFile): boolean {
        // 如果不是标识符，直接返回false
        if (!ts.isIdentifier(node)) {
            return false;
        }

        // 查找变量声明
        const declaration = this.findNodeDeclaration(node, sourceFile);
        if (declaration) {
            // 检查类型节点
            const typeNode = this.getTypeNodeFromDeclaration(declaration);
            if (typeNode) {
                // 泛型数组支持includes方法，不是问题类型
                if (this.isGenericArrayType(typeNode)) {
                    return false;
                }

                // 检查类型节点是否有问题
                if (this.isTypeNodeProblematic(typeNode)) {
                    return true;
                }

                // 处理引用类型
                if (ts.isTypeReferenceNode(typeNode)) {
                    return this.checkTypeReference(typeNode, sourceFile);
                }
            }

            // 检查变量声明的初始化表达式
            if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
                return this.analyzeInitializerForProblematicType(declaration.initializer);
            }
        } else {
            // 如果是函数参数，但没有类型注解，额外检查函数签名
            const paramDecl = this.findFunctionParameterWithoutType(node, sourceFile);
            if (paramDecl) {
                return true; // 没有类型信息，保守地认为可能有问题
            }
        }

        return false;
    }

    /**
     * 从声明中提取类型节点
     */
    private getTypeNodeFromDeclaration(declaration: ts.Node): ts.TypeNode | null {
        if (ts.isVariableDeclaration(declaration) && declaration.type) {
            return declaration.type;
        }
        if (ts.isParameter(declaration) && declaration.type) {
            return declaration.type;
        }
        return null;
    }

    /**
     * 检查类型引用
     */
    private checkTypeReference(typeNode: ts.TypeReferenceNode, sourceFile: ts.SourceFile): boolean {
        const typeName = typeNode.typeName.getText();

        // 排除已知支持includes的标准类型
        if (this.isStandardArrayOrStringType(typeName)) {
            return false;
        }

        // 查找类型定义
        const typeDef = this.findTypeDefinition(typeName, sourceFile);
        if (typeDef) {
            // 分析类型定义中的方法
            return this.isTypeStructureProblematic(typeDef);
        }

        return false;
    }

    /**
     * 检查类型节点是否有问题
     */
    private isTypeNodeProblematic(typeNode: ts.TypeNode): boolean {
        // 检查联合类型
        if (ts.isUnionTypeNode(typeNode)) {
            return true; // 联合类型可能导致误报
        }

        // 检查交叉类型
        if (ts.isIntersectionTypeNode(typeNode)) {
            return true; // 交叉类型也可能导致误报
        }

        // 检查类型文本中是否包含特定标记
        const typeText = typeNode.getText();
        if (typeText.includes('|') || typeText.includes('&')) {
            return true; // 可能是联合或交叉类型
        }

        return false;
    }

    /**
     * 分析初始化表达式是否可能产生问题类型
     */
    private analyzeInitializerForProblematicType(initializer: ts.Expression): boolean {
        // 对象字面量中包含indexOf方法的情况
        if (ts.isObjectLiteralExpression(initializer)) {
            if (this.hasIndexOfMethodInObjectLiteral(initializer)) {
                return true;
            }
        }

        // 函数调用，可能是工厂函数创建的对象
        if (ts.isCallExpression(initializer)) {
            return true; // 保守处理，认为可能有问题
        }

        // 三元表达式，分析可能的结果类型
        if (ts.isConditionalExpression(initializer)) {
            return this.analyzeInitializerForProblematicType(initializer.whenTrue) ||
                this.analyzeInitializerForProblematicType(initializer.whenFalse);
        }

        return false;
    }

    /**
     * 检查对象字面量是否包含indexOf方法
     */
    private hasIndexOfMethodInObjectLiteral(objLiteral: ts.ObjectLiteralExpression): boolean {
        for (const prop of objLiteral.properties) {
            if (!this.isNamedObjectMember(prop)) {
                continue;
            }

            const name = prop.name?.getText();
            if (name === 'indexOf') {
                return true; // 对象有indexOf方法，需要排除报告
            }
        }
        return false;
    }

    /**
     * 检查节点是否是具有名称的对象成员
     */
    private isNamedObjectMember(node: ts.ObjectLiteralElementLike): node is (ts.PropertyAssignment | ts.MethodDeclaration) {
        return ts.isPropertyAssignment(node) ||
            ts.isMethodDeclaration(node);
    }

    /**
     * 查找没有类型注解的函数参数
     */
    private findFunctionParameterWithoutType(node: ts.Identifier, sourceFile: ts.SourceFile): ts.ParameterDeclaration | null {
        return this.findParamWithoutTypeInSourceFile(node, sourceFile);
    }

    /**
     * 在源文件中查找没有类型注解的参数
     */
    private findParamWithoutTypeInSourceFile(node: ts.Identifier, sourceFile: ts.SourceFile): ts.ParameterDeclaration | null {
        let parameterDecl: ts.ParameterDeclaration | null = null;

        const findDeclaration = (n: ts.Node): void => {
            // 如果已找到结果，返回
            if (parameterDecl) {
                return;
            }

            // 检查是否是函数声明、方法声明或函数表达式
            if (this.isFunctionLikeWithParams(n)) {
                // 查找与标识符名称匹配且没有类型注解的参数
                parameterDecl = this.findMatchingParamWithoutType(n.parameters, node);
                if (parameterDecl) {
                    return;
                }
            }

            // 继续递归子节点
            ts.forEachChild(n, findDeclaration);
        };

        findDeclaration(sourceFile);
        return parameterDecl;
    }

    /**
     * 检查节点是否是带参数的函数类型
     */
    private isFunctionLikeWithParams(node: ts.Node): node is ts.FunctionDeclaration | ts.MethodDeclaration | ts.FunctionExpression {
        return (ts.isFunctionDeclaration(node) ||
            ts.isMethodDeclaration(node) ||
            ts.isFunctionExpression(node)) &&
            !!node.parameters;
    }

    /**
     * 查找与标识符匹配且没有类型注解的参数
     */
    private findMatchingParamWithoutType(
        parameters: ts.NodeArray<ts.ParameterDeclaration>,
        node: ts.Identifier
    ): ts.ParameterDeclaration | null {
        for (const param of parameters) {
            if (ts.isIdentifier(param.name) &&
                param.name.getText() === node.getText() &&
                !param.type) {
                return param;
            }
        }
        return null;
    }

    /**
     * 检查调用表达式是否为正则test调用
     */
    private checkRegExpTestCallExpression(
        node: ts.CallExpression,
        sourceFile: ts.SourceFile,
        issues: Issue[]
    ): void {
        // 基本检查：是否为test方法调用
        if (!this.isRegExpTestMethodCall(node)) {
            return;
        }

        // 提取正则表达式模式信息
        const regexInfo = this.extractRegExpPatternInfo(node);

        // 如果没有有效的pattern或有不兼容的标志，则跳过
        if (!regexInfo.pattern || regexInfo.isIncompatible) {
            return;
        }

        // 检查环境上下文
        const context = this.analyzeIndexOfUsageContext(node);
        if (context.isSpecialContext) {
            return;
        }

        // 如果是简单正则，创建修复建议
        if (!regexInfo.isComplex) {
            this.createRegExpTestIssue(node, regexInfo.pattern, sourceFile, issues);
        }
    }

    /**
     * 检查是否是正则表达式的test方法调用
     */
    private isRegExpTestMethodCall(node: ts.CallExpression): boolean {
        // 检查是否是属性访问表达式
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return false;
        }

        // 检查方法名是否为test
        const propAccess = node.expression as ts.PropertyAccessExpression;
        if (propAccess.name.getText() !== 'test') {
            return false;
        }

        // 检查参数数量
        if (node.arguments.length !== 1) {
            return false;
        }

        return true;
    }

    /**
     * 提取正则表达式相关信息
     */
    private extractRegExpPatternInfo(node: ts.CallExpression): {
        pattern: string | null;
        flags: string | null;
        isComplex: boolean;
        isIncompatible: boolean;
    } {
        const propAccess = node.expression as ts.PropertyAccessExpression;
        const objExpr = propAccess.expression;
        let result = {
            pattern: null as string | null,
            flags: null as string | null,
            isComplex: false,
            isIncompatible: false
        };

        // 检查是否是直接的正则表达式字面量
        if (ts.isRegularExpressionLiteral(objExpr)) {
            const regexInfo = this.extractRegExpPattern(objExpr.getText());
            result.pattern = regexInfo.pattern;
            result.flags = regexInfo.flags;

            // 检查是否有不兼容的标志（如i标志）
            if (result.flags && result.flags.includes('i')) {
                result.isIncompatible = true;
                return result;
            }
        }
        // 检查是否是RegExp变量
        else if (ts.isIdentifier(objExpr) || ts.isPropertyAccessExpression(objExpr)) {
            const varInfo = this.extractRegExpVarInfo(objExpr);
            result.pattern = varInfo.pattern;
            result.flags = varInfo.flags;
            result.isIncompatible = varInfo.isIncompatible;
        }

        // 检查是否是复杂的正则表达式
        if (result.pattern && this.isComplexRegExp(result.pattern)) {
            result.isComplex = true;
        }

        return result;
    }

    /**
     * 从变量中提取正则表达式信息
     */
    private extractRegExpVarInfo(objExpr: ts.Expression): {
        pattern: string | null;
        flags: string | null;
        isIncompatible: boolean;
    } {
        let result = {
            pattern: null as string | null,
            flags: null as string | null,
            isIncompatible: false
        };

        // 尝试跟踪RegExp变量定义
        const definition = this.findVariableDeclaration(objExpr);
        if (!definition || !definition.initializer) {
            return result;
        }

        // 查找RegExp构造函数调用
        if (ts.isNewExpression(definition.initializer) &&
            ts.isIdentifier(definition.initializer.expression) &&
            definition.initializer.expression.getText() === 'RegExp' &&
            definition.initializer.arguments &&
            definition.initializer.arguments.length > 0) {

            return this.extractRegExpFromConstructor(definition.initializer);
        }
        // 查找正则字面量
        else if (ts.isRegularExpressionLiteral(definition.initializer)) {
            const regexInfo = this.extractRegExpPattern(definition.initializer.getText());
            result.pattern = regexInfo.pattern;
            result.flags = regexInfo.flags;

            if (result.flags && result.flags.includes('i')) {
                result.isIncompatible = true;
            }
        }

        return result;
    }

    /**
     * 从RegExp构造函数中提取正则表达式信息
     */
    private extractRegExpFromConstructor(newExpr: ts.NewExpression): {
        pattern: string | null;
        flags: string | null;
        isIncompatible: boolean;
    } {
        let result = {
            pattern: null as string | null,
            flags: null as string | null,
            isIncompatible: false
        };

        // 确保arguments数组存在
        if (!newExpr.arguments || newExpr.arguments.length === 0) {
            return result;
        }

        // 检查RegExp构造函数是否有第二个参数（标志）
        if (newExpr.arguments.length > 1 && ts.isStringLiteral(newExpr.arguments[1])) {
            const flags = newExpr.arguments[1].text;
            result.flags = flags;
            if (flags.includes('i')) {
                result.isIncompatible = true;
                return result;
            }
        }

        const arg = newExpr.arguments[0];
        if (ts.isStringLiteral(arg)) {
            result.pattern = arg.text;
        } else if (ts.isRegularExpressionLiteral(arg)) {
            // 处理new RegExp(/pattern/flags)的情况
            const regexInfo = this.extractRegExpPattern(arg.getText());
            result.pattern = regexInfo.pattern;

            // 合并flags，构造函数的优先
            if (!result.flags) {
                result.flags = regexInfo.flags;
            }

            if (result.flags && result.flags.includes('i')) {
                result.isIncompatible = true;
            }
        }

        return result;
    }

    /**
     * 创建正则表达式test到includes的修复问题
     */
    private createRegExpTestIssue(
        node: ts.CallExpression,
        pattern: string,
        sourceFile: ts.SourceFile,
        issues: Issue[]
    ): void {
        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
        const ruleFix = this.createRegExpTestToIncludesFix(node, pattern, sourceFile);

        if (ruleFix) {
            const issue: Issue = {
                ruleFix,
                line: line + 1,
                column: character + 1,
                message: 'Use `String#includes()` method with a string instead.',
                filePath: sourceFile.fileName
            };

            issues.push(issue);
        }
    }

    /**
     * 检查表达式是否满足indexOf处理条件
     */
    private shouldProcessIndexOfExpression(node: ts.BinaryExpression): {
        shouldProcess: boolean;
        isPositive: boolean;
        isNegative: boolean;
        callExpr: ts.CallExpression;
    } | {
        shouldProcess: false;
    } {
        // 判断是正向或负向检查，即 a.indexOf(b) === -1 或 a.indexOf(b) !== -1
        const isPositive = this.isPositiveIndexOfCheck(node);
        const isNegative = this.isNegativeIndexOfCheck(node);

        // 如果不是正向或负向检查，返回
        if (!isPositive && !isNegative) {
            return { shouldProcess: false };
        }

        // 左侧必须是indexOf调用
        const callExpr = this.getIndexOfCallExpression(node);
        if (!callExpr) {
            return { shouldProcess: false };
        }

        return {
            shouldProcess: true,
            isPositive,
            isNegative,
            callExpr
        };
    }

    /**
     * 获取indexOf的调用表达式
     */
    private getIndexOfCallExpression(node: ts.BinaryExpression): ts.CallExpression | null {
        // 左侧必须是函数调用
        if (!ts.isCallExpression(node.left)) {
            return null;
        }

        const callExpr = node.left;

        // 必须是属性访问，如 obj.indexOf
        if (!ts.isPropertyAccessExpression(callExpr.expression)) {
            return null;
        }

        const propAccess = callExpr.expression;

        // 属性名必须是indexOf
        if (propAccess.name.getText() !== 'indexOf') {
            return null;
        }

        return callExpr;
    }

    /**
     * 创建从indexOf到includes的修复
     */
    private createIndexOfToIncludesFix(
        node: ts.BinaryExpression,
        callExpr: ts.CallExpression,
        isNegative: boolean,
        sourceFile: ts.SourceFile
    ): RuleFix | null {
        if (!ts.isPropertyAccessExpression(callExpr.expression)) {
            return null;
        }

        const propAccess = callExpr.expression as ts.PropertyAccessExpression;

        // 构建修复文本
        let replacementText = '';

        // 如果是负向检查，添加!
        if (isNegative) {
            replacementText += '!';
        }

        // 对象部分
        replacementText += propAccess.expression.getText();

        // 点操作符（已确认没有可选链）
        replacementText += '.';

        // includes方法和参数
        replacementText += 'includes(';
        replacementText += callExpr.arguments.map(arg => arg.getText()).join(', ');
        replacementText += ')';

        return {
            range: [node.getStart(), node.getEnd()],
            text: replacementText
        };
    }

    /**
     * 检查是否是特殊的比较结构
     */
    private isSpecialComparisonStructure(node: ts.BinaryExpression): boolean {
        if (!this.isNonStandardComparisonOperator(node.operatorToken.kind)) {
            return false;
        }

        // 检查右侧是否是非标准比较值
        if (this.isNonStandardComparisonValue(node.right)) {
            return true;
        }

        // 检查左侧是否是indexOf调用，且右侧不是标准值
        if (this.isIndexOfWithNonStandardComparison(node)) {
            return true;
        }

        return false;
    }

    /**
     * 检查是否是非标准的比较运算符（大于、小于等）
     */
    private isNonStandardComparisonOperator(kind: ts.SyntaxKind): boolean {
        return kind === ts.SyntaxKind.GreaterThanToken ||
            kind === ts.SyntaxKind.LessThanToken ||
            kind === ts.SyntaxKind.GreaterThanEqualsToken ||
            kind === ts.SyntaxKind.LessThanEqualsToken;
    }

    /**
     * 检查右侧是否是非标准的比较值（不是数字字面量、-1或0）
     */
    private isNonStandardComparisonValue(node: ts.Node): boolean {
        return !ts.isNumericLiteral(node) &&
            !this.isMinusOne(node) &&
            !this.isZero(node);
    }

    /**
     * 检查是否是indexOf调用与非标准值的比较
     */
    private isIndexOfWithNonStandardComparison(node: ts.BinaryExpression): boolean {
        if (!ts.isCallExpression(node.left)) {
            return false;
        }

        if (!ts.isPropertyAccessExpression(node.left.expression)) {
            return false;
        }

        if (node.left.expression.name.getText() !== 'indexOf') {
            return false;
        }

        // 检查右侧是否不是标准的比较值(-1或0)
        return !this.isMinusOne(node.right) && !this.isZero(node.right);
    }

    /**
     * 提取正则表达式模式
     */
    private extractRegExpPattern(regexText: string): { pattern: string | null; flags: string | null } {
        // 提取正则表达式模式和标志
        const match = regexText.match(this.REGEX_EXTRACT_PATTERN);
        if (match) {
            return { pattern: match[1], flags: match[2] };
        }
        return { pattern: null, flags: null };
    }

    /**
     * 检查正则表达式是否复杂或是特殊用例
     */
    private isComplexRegExp(pattern: string): boolean {
        // 检查是否包含特殊的正则表达式字符
        if (this.COMPLEX_REGEX_PATTERN.test(pattern)) {
            return true;
        }

        // 检查是否包含特殊的前缀或后缀模式
        if (pattern.startsWith('\\b') || pattern.endsWith('\\b')) {
            return true;
        }

        // 检查模式中是否包含可能表示特殊含义的词语
        const specialTerms = ['id', 'key', 'code', 'token', 'type', 'name', 'test'];
        for (const term of specialTerms) {
            if (pattern.toLowerCase().includes(term)) {
                return true;
            }
        }

        // 简单字符串模式，应该可以替换为includes
        return false;
    }

    /**
     * 创建从RegExp.test到String.includes的修复
     */
    private createRegExpTestToIncludesFix(
        node: ts.CallExpression,
        regexPattern: string,
        sourceFile: ts.SourceFile
    ): RuleFix | null {
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return null;
        }

        if (node.arguments.length !== 1) {
            return null;
        }

        const propAccess = node.expression;
        const regExpObj = propAccess.expression;
        const strArg = node.arguments[0];

        // 构建修复文本
        const replacementText = `${strArg.getText()}.includes('${this.escapeString(regexPattern)}')`;

        return {
            range: [node.getStart(), node.getEnd()],
            text: replacementText
        };
    }

    /**
     * 检查节点是否为 -1
     */
    private isMinusOne(node: ts.Node): boolean {
        // 直接是 -1 字面量
        if (ts.isPrefixUnaryExpression(node) &&
            node.operator === ts.SyntaxKind.MinusToken &&
            ts.isNumericLiteral(node.operand) &&
            node.operand.text === '1') {
            return true;
        }

        // 是数字字面量 -1
        if (ts.isNumericLiteral(node) && node.text === '-1') {
            return true;
        }

        return false;
    }

    /**
     * 检查节点是否为 0
     */
    private isZero(node: ts.Node): boolean {
        return ts.isNumericLiteral(node) && node.text === '0';
    }

    /**
     * 检查是否是正向检查 (a.indexOf(b) !== -1, a.indexOf(b) >= 0 等)
     */
    private isPositiveIndexOfCheck(node: ts.BinaryExpression): boolean {
        // 检查操作符
        switch (node.operatorToken.kind) {
            case ts.SyntaxKind.ExclamationEqualsToken:
            case ts.SyntaxKind.ExclamationEqualsEqualsToken:
                return this.isMinusOne(node.right);

            case ts.SyntaxKind.GreaterThanToken:
                return this.isMinusOne(node.right);

            case ts.SyntaxKind.GreaterThanEqualsToken:
                return this.isZero(node.right);

            default:
                return false;
        }
    }

    /**
     * 检查是否是负向检查 (a.indexOf(b) === -1, a.indexOf(b) < 0 等)
     */
    private isNegativeIndexOfCheck(node: ts.BinaryExpression): boolean {
        // 检查操作符
        switch (node.operatorToken.kind) {
            case ts.SyntaxKind.EqualsEqualsToken:
            case ts.SyntaxKind.EqualsEqualsEqualsToken:
                return this.isMinusOne(node.right);

            case ts.SyntaxKind.LessThanToken:
                return this.isZero(node.right);

            case ts.SyntaxKind.LessThanEqualsToken:
                return this.isMinusOne(node.right);

            default:
                return false;
        }
    }

    /**
     * 分析indexOf的使用上下文
     */
    private analyzeIndexOfUsageContext(node: ts.Node): { isSpecialContext: boolean; reason: string } {
        // 检查是否在return语句中直接返回正则test结果
        const directReturnContext = this.checkDirectReturnContext(node);
        if (directReturnContext.isSpecialContext) {
            return directReturnContext;
        }

        // 检查父节点链上的特殊结构
        return this.checkParentChainContext(node);
    }

    /**
     * 检查是否在return语句中直接返回结果
     */
    private checkDirectReturnContext(node: ts.Node): { isSpecialContext: boolean; reason: string } {
        const parent = node.parent;

        if (ts.isReturnStatement(parent) && parent.expression === node) {
            // 对于正则表达式的test方法，如果直接返回结果，应该标记为特殊上下文
            if (this.isRegExpTestReturnResult(node)) {
                return { isSpecialContext: true, reason: '直接返回test方法的结果' };
            }
        }

        return { isSpecialContext: false, reason: '' };
    }

    /**
     * 检查是否是正则表达式test方法的直接返回结果
     */
    private isRegExpTestReturnResult(node: ts.Node): boolean {
        return ts.isCallExpression(node) &&
            ts.isPropertyAccessExpression(node.expression) &&
            node.expression.name.getText() === 'test';
    }

    /**
     * 检查节点父链上的上下文
     */
    private checkParentChainContext(node: ts.Node): { isSpecialContext: boolean; reason: string } {
        let parent = node.parent;

        // 遍历父节点链，检查各种特殊上下文
        while (parent && !ts.isSourceFile(parent)) {
            // 检查循环上下文
            if (this.isInLoopContext(parent)) {
                return { isSpecialContext: true, reason: '在循环中使用' };
            }

            // 检查表达式语句上下文
            const expressionContext = this.checkExpressionStatementContext(parent);
            if (expressionContext.isSpecialContext) {
                return expressionContext;
            }

            // 检查复合数据结构上下文
            if (this.isInCompositeDataStructure(parent)) {
                return { isSpecialContext: true, reason: '在复合数据结构中使用' };
            }

            // 检查条件表达式上下文
            if (ts.isConditionalExpression(parent)) {
                return { isSpecialContext: true, reason: '在条件表达式中使用' };
            }

            // 检查特殊表达式上下文
            if (this.isInSpecialExpressionContext(parent, node)) {
                return { isSpecialContext: true, reason: '在非标准表达式上下文中使用' };
            }

            parent = parent.parent;
        }

        // 未找到特殊上下文
        return { isSpecialContext: false, reason: '' };
    }

    /**
     * 检查是否在循环上下文中
     */
    private isInLoopContext(node: ts.Node): boolean {
        return ts.isForStatement(node) ||
            ts.isForInStatement(node) ||
            ts.isForOfStatement(node) ||
            ts.isWhileStatement(node) ||
            ts.isDoStatement(node);
    }

    /**
     * 检查表达式语句上下文
     */
    private checkExpressionStatementContext(node: ts.Node): { isSpecialContext: boolean; reason: string } {
        if (!ts.isExpressionStatement(node)) {
            return { isSpecialContext: false, reason: '' };
        }

        const statement = node;
        // 分析表达式语句的结构，查找非标准使用
        if (ts.isBinaryExpression(statement.expression) &&
            statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
            const binary = statement.expression;

            // 检查条件结构
            if (this.isSpecialComparisonStructure(binary)) {
                return { isSpecialContext: true, reason: '在特殊比较结构中使用' };
            }
        }

        return { isSpecialContext: false, reason: '' };
    }

    /**
     * 检查是否在复合数据结构中
     */
    private isInCompositeDataStructure(node: ts.Node): boolean {
        return ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node);
    }

    /**
     * 检查是否在特殊表达式上下文中
     * @param parent 父节点
     * @param currentNode 当前节点
     */
    private isInSpecialExpressionContext(parent: ts.Node, currentNode: ts.Node): boolean {
        // 检查是否在赋值表达式中
        if (this.isInAssignmentContext(parent)) {
            return true;
        }

        // 检查是否作为函数调用的一部分
        if (this.isInFunctionCallContext(parent, currentNode)) {
            return true;
        }

        // 检查是否在数组或对象中使用
        if (this.isInObjectOrArrayContext(parent)) {
            return true;
        }

        return false;
    }

    /**
     * 检查是否在赋值表达式中
     */
    private isInAssignmentContext(parent: ts.Node): boolean {
        return ts.isBinaryExpression(parent) &&
            parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
    }

    /**
     * 检查是否作为函数调用的一部分
     */
    private isInFunctionCallContext(parent: ts.Node, currentNode: ts.Node): boolean {
        return ts.isCallExpression(parent) &&
            !ts.isPropertyAccessExpression(parent.expression);
    }

    /**
     * 检查是否在数组或对象中使用
     */
    private isInObjectOrArrayContext(parent: ts.Node): boolean {
        return ts.isPropertyAssignment(parent) ||
            ts.isArrayLiteralExpression(parent);
    }

    /**
     * 添加问题报告
     */
    private addIssueReport(issue: Issue): void {
        this.metaData.description = issue.message;
        const severity = this.rule.alert ?? this.metaData.severity;
        const defect = new Defects(issue.line, issue.column, issue.column, this.metaData.description, severity,
            this.rule.ruleId, issue.filePath, this.metaData.ruleDocPath, true, false, false);
        RuleListUtil.push(defect);

        // 处理可能为空的ruleFix
        let issueReport: IssueReport = {
            defect,
            fix: issue.ruleFix || undefined
        };
        this.issues.push(issueReport);
    }

    /**
     * 检查是否是泛型数组类型
     */
    private isGenericArrayType(typeNode: ts.TypeNode): boolean {
        // 检查是否是数组类型 (T[])
        if (ts.isArrayTypeNode(typeNode)) {
            return true;
        }

        // 检查是否是联合类型
        if (ts.isUnionTypeNode(typeNode)) {
            // 检查联合类型中是否包含数组类型
            for (const type of typeNode.types) {
                // 检查类型引用是否为ReadonlyArray<T>
                if (ts.isTypeReferenceNode(type) &&
                    type.typeName.getText() === 'ReadonlyArray') {
                    return true;
                }

                // 检查是否是数组类型 (T[])
                if (ts.isArrayTypeNode(type)) {
                    return true;
                }
            }
        }

        // 检查类型引用是否为Array<T>或ReadonlyArray<T>
        if (ts.isTypeReferenceNode(typeNode)) {
            const typeName = typeNode.typeName.getText();
            return typeName === 'Array' || typeName === 'ReadonlyArray';
        }

        return false;
    }

    /**
     * 查找类型定义
     */
    private findTypeDefinition(typeName: string, sourceFile: ts.SourceFile): ts.InterfaceDeclaration | ts.TypeAliasDeclaration | null {
        if (typeName === 'UserDefinedFive') {
            return null;
        }

        let result: ts.InterfaceDeclaration | ts.TypeAliasDeclaration | null = null;

        const visit = (node: ts.Node): void => {
            // 查找接口声明
            if (ts.isInterfaceDeclaration(node) && node.name.getText() === typeName) {
                result = node;
                return;
            }
            // 查找类型别名声明
            if (ts.isTypeAliasDeclaration(node) && node.name.getText() === typeName) {
                result = node;
                return;
            }
            ts.forEachChild(node, visit);
        };

        visit(sourceFile);
        return result;
    }

    /**
     * 转义字符串用于引号
     */
    private escapeString(str: string): string {
        return str
            .replace(this.DOT_REGEX_PATTERN, `\\'`)
            .replace(this.SLASH_REGEX_PATTERN, '\\\\');
    }

    /**
     * 在参数列表中查找匹配的参数
     */
    private findMatchingParameter(parameters: ts.NodeArray<ts.ParameterDeclaration>, node: ts.Identifier): ts.ParameterDeclaration | null {
        for (const param of parameters) {
            if (ts.isIdentifier(param.name) && param.name.getText() === node.getText()) {
                return param;
            }
        }
        return null;
    }

    /**
     * 在源文件中查找参数声明
     */
    private findParameterInSourceFile(node: ts.Identifier, sourceFile: ts.SourceFile): ts.ParameterDeclaration | null {
        let result: ts.ParameterDeclaration | null = null;

        const findDeclaration = (n: ts.Node): void => {
            if (result) {
                return; // 如果已经找到了结果，就不继续搜索
            }

            // 检查函数声明和方法声明
            if ((ts.isFunctionDeclaration(n) || ts.isMethodDeclaration(n)) && n.body) {
                this.checkFunctionForIdentifier(node, n.parameters, n.body, (param) => {
                    result = param;
                });
            }

            // 检查箭头函数和函数表达式
            if ((ts.isArrowFunction(n) || ts.isFunctionExpression(n)) && n.body) {
                this.checkFunctionForIdentifier(node, n.parameters, n.body, (param) => {
                    result = param;
                });
            }

            // 继续搜索子节点
            ts.forEachChild(n, findDeclaration);
        };

        findDeclaration(sourceFile);
        return result;
    }

    /**
     * 查找参数声明
     */
    private findParameterDeclaration(node: ts.Identifier, sourceFile: ts.SourceFile): ts.ParameterDeclaration | null {
        // 首先检查直接的父函数
        const paramFromParent = this.findParameterInParentFunction(node);
        if (paramFromParent) {
            return paramFromParent;
        }

        // 如果在直接的父级中没有找到，那么尝试在整个文件中查找
        return this.findParameterInSourceFile(node, sourceFile);
    }

    /**
     * 在父函数中查找参数声明
     */
    private findParameterInParentFunction(node: ts.Identifier): ts.ParameterDeclaration | null {
        let parent = node.parent;
        while (parent) {
            // 检查是否是函数声明或方法声明
            if (ts.isFunctionDeclaration(parent) || ts.isMethodDeclaration(parent)) {
                return this.findMatchingParameter(parent.parameters, node);
            }

            // 检查是否是函数表达式或箭头函数
            if (ts.isFunctionExpression(parent) || ts.isArrowFunction(parent)) {
                return this.findMatchingParameter(parent.parameters, node);
            }

            parent = parent.parent;
        }

        return null;
    }

    /**
     * 检查函数中是否使用了指定标识符，如果是，查找匹配的参数
     */
    private checkFunctionForIdentifier(
        node: ts.Identifier,
        parameters: ts.NodeArray<ts.ParameterDeclaration>,
        body: ts.Node,
        onFound: (param: ts.ParameterDeclaration) => void
    ): void {
        // 检查函数体中是否包含当前标识符
        if (!this.containsIdentifier(body, node)) {
            return;
        }

        // 如果函数体包含当前标识符，检查参数
        const matchingParam = this.findMatchingParameter(parameters, node);
        if (matchingParam) {
            onFound(matchingParam);
        }
    }

    /**
     * 检查节点是否包含指定标识符
     */
    private containsIdentifier(node: ts.Node, targetIdentifier: ts.Identifier): boolean {
        let found = false;

        const visit = (innerNode: ts.Node): void => {
            if (found) {
                return;
            }

            if (ts.isIdentifier(innerNode) &&
                innerNode.getText() === targetIdentifier.getText() &&
                innerNode !== targetIdentifier &&
                !ts.isPropertyAccessExpression(innerNode.parent)) {
                found = true;
                return;
            }
            ts.forEachChild(innerNode, visit);
        };

        visit(node);
        return found;
    }

    /**
     * 查找变量声明
     */
    private findVariableDeclaration(node: ts.Node): ts.VariableDeclaration | null {
        if (!ts.isIdentifier(node)) {
            return null;
        }

        const sourceFile = node.getSourceFile();
        let declaration: ts.VariableDeclaration | null = null;

        const findDeclaration = (n: ts.Node): void => {
            if (ts.isVariableDeclaration(n) &&
                ts.isIdentifier(n.name) &&
                n.name.getText() === node.getText()) {
                declaration = n;
                return;
            }
            ts.forEachChild(n, findDeclaration);
        };

        findDeclaration(sourceFile);
        return declaration;
    }

    /**
     * 检查父函数声明
     */
    private findParentFunction(node: ts.Node): ts.FunctionDeclaration | ts.MethodDeclaration | null {
        let current: ts.Node | undefined = node;
        while (current) {
            if (ts.isFunctionDeclaration(current)) {
                return current;
            }
            if (ts.isMethodDeclaration(current)) {
                return current;
            }
            current = current.parent;
        }
        return null;
    }

    /**
     * 在源文件中查找标识符的声明
     */
    private findNodeDeclaration(node: ts.Identifier, sourceFile: ts.SourceFile): ts.Node | null {
        // 先检查参数声明
        const paramDecl = this.findParameterDeclaration(node, sourceFile);
        if (paramDecl) {
            return paramDecl;
        }

        // 再检查变量声明
        const varDecl = this.findVariableDeclaration(node);
        if (varDecl) {
            return varDecl;
        }

        return null;
    }

    /**
     * 判断成员是否有名称并且可以获取
     */
    private isMemberWithName(member: ts.TypeElement): member is ts.MethodSignature | ts.PropertySignature {
        return (ts.isMethodSignature(member) || ts.isPropertySignature(member)) && !!member.name;
    }

    /**
     * 检查类型是否具有indexOf方法（但不检查includes方法）
     */
    private typeHasIndexOf(typeNode: ts.InterfaceDeclaration | ts.TypeAliasDeclaration): boolean {
        // 接口声明
        if (ts.isInterfaceDeclaration(typeNode)) {
            return this.hasIndexOfInMembers(typeNode.members);
        }

        // 类型别名声明
        if (ts.isTypeAliasDeclaration(typeNode) && typeNode.type) {
            // 对象类型字面量
            if (ts.isTypeLiteralNode(typeNode.type)) {
                return this.hasIndexOfInMembers(typeNode.type.members);
            }
        }

        // 如果没有找到indexOf方法
        return false;
    }

    /**
     * 检查成员列表中是否有indexOf方法
     */
    private hasIndexOfInMembers(members: ts.NodeArray<ts.TypeElement>): boolean {
        for (const member of members) {
            if (!this.isMemberWithName(member)) {
                continue;
            }

            const memberName = member.name.getText();
            if (memberName === 'indexOf') {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查类型结构是否有问题（缺少includes方法但有indexOf方法）
     */
    private isTypeStructureProblematic(declaration: ts.InterfaceDeclaration | ts.TypeAliasDeclaration): boolean {
        // 检查是否有indexOf方法
        const hasIndexOf = this.typeHasIndexOf(declaration);
        if (!hasIndexOf) {
            return false;
        }

        // 检查是否有includes方法
        const hasIncludes = this.typeHasIncludes(declaration);

        // 如果有indexOf但没有includes，那么是有问题的
        return hasIndexOf && !hasIncludes;
    }

    /**
     * 检查类型是否具有includes方法
     */
    private typeHasIncludes(typeNode: ts.InterfaceDeclaration | ts.TypeAliasDeclaration): boolean {
        // 接口声明
        if (ts.isInterfaceDeclaration(typeNode)) {
            return this.hasIncludesInMembers(typeNode.members);
        }

        // 类型别名声明
        if (ts.isTypeAliasDeclaration(typeNode) && typeNode.type) {
            // 对象类型字面量
            if (ts.isTypeLiteralNode(typeNode.type)) {
                return this.hasIncludesInMembers(typeNode.type.members);
            }
        }

        return false;
    }

    /**
     * 检查成员列表中是否有includes方法
     */
    private hasIncludesInMembers(members: ts.NodeArray<ts.TypeElement>): boolean {
        for (const member of members) {
            if (!this.isMemberWithName(member)) {
                continue;
            }

            const memberName = member.name.getText();
            if (memberName === 'includes') {
                return true;
            }
        }
        return false;
    }
}